using System;
using Slaks.DocumentSerialization.Dictionary;
using Slaks.DocumentSerialization.Document.Wordnet;

namespace Slaks.VectorBasics.VectorBuilder.ExperimentalRepresentations
{
	public class StandardWordnetSensesRepresentation
	{
		public static Vector Build(WordnetDocument document, DictionaryMap dictionaryMap)
		{
			string documentName = document.FileName;
			int index = documentName.LastIndexOfAny(new char[] {'\\', '/'});
			if (index >= 0 && (index + 1 < documentName.Length)) documentName = documentName.Substring(index + 1);
			Vector vector = new Vector(documentName);

			#region find frequent node

			double frequentNode = double.MinValue;
			foreach (WordnetNode node in document.Nodes)
			{
				if (node.TotalTermFrequency*GetSenseProbability(node) > frequentNode)
					frequentNode = node.TotalTermFrequency*GetSenseProbability(node);
			}

			#endregion

			VectorItem vectorItem;
			foreach (WordnetNode node in document.Nodes)
			{
				if (dictionaryMap.Contains(node.Id))
				{
					vectorItem = vector.CreateAddVectorItem(node.Id);
					//vectorItem.Frequency = (double) node.TotalTermFrequency/document.UniqueTermCount;
					//vectorItem.Frequency = (double) node.TotalTermFrequency * GetSenseProbability(node) / document.UniqueTermCount;
					vectorItem.Frequency = (node.TotalTermFrequency*GetSenseProbability(node))/frequentNode;
				}

			}

			if (vector.GetVectorLength() == 0) throw new VectorException(String.Format("Length of the vector {0} is zero", documentName));

			return vector;
		}

		protected static double GetSenseProbability(WordnetNode node)
		{
			//if (node.SenseInfo.GetTotalSenses() <= 2) return 0.1;
			//else if (node.SenseInfo.GetTotalSenses() >= 10) return 0.001;
			//return ((double) 1/node.SenseInfo.GetTotalSenses());
			double noun = node.SenseInfo.Nouns;
			double verb = node.SenseInfo.Verbs;
			double adj = node.SenseInfo.Adjectives;
			double adv = node.SenseInfo.Adverbs;

			if (noun > verb)
			{
				if (noun > adj && noun > adv) return 1;
				else return 0.1;
			}
			else
			{
				if (verb > adj && verb > adv) return 0.5;
				else return 0.1;
			}
		}
	}
}